package sdk.webview.fmc.com.fmcsdk.util.retrofit2.subscriber;

import android.app.Application;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import javax.net.ssl.SSLHandshakeException;

import retrofit2.adapter.rxjava.HttpException;
import sdk.webview.fmc.com.fmcsdk.R;
import sdk.webview.fmc.com.fmcsdk.activity.ForgetPwdActivity;
import sdk.webview.fmc.com.fmcsdk.activity.H5Activity;
import sdk.webview.fmc.com.fmcsdk.activity.LoginActivity;
import sdk.webview.fmc.com.fmcsdk.activity.PresionInfoActivity;
import sdk.webview.fmc.com.fmcsdk.base.BaseData;
import sdk.webview.fmc.com.fmcsdk.base.BaseView;
import sdk.webview.fmc.com.fmcsdk.bean.ErrorEvnet;
import sdk.webview.fmc.com.fmcsdk.bean.SystemSetting;
import sdk.webview.fmc.com.fmcsdk.interfaces.OnDialogSureListener;
import sdk.webview.fmc.com.fmcsdk.util.Constant;
import sdk.webview.fmc.com.fmcsdk.util.DialogUtils;
import sdk.webview.fmc.com.fmcsdk.util.ToastUtils;
import sdk.webview.fmc.com.fmcsdk.util.Utility;
import sdk.webview.fmc.com.fmcsdk.view.ErrorDialog;


/**
 * 网络结果处理类, 此类会判断网络错误与业务错误.
 *
 * <p>
 * {@link ResponseSubscriber}与 ResponseAction均是调用此类来实现网络结果判断, 错误处理,
 * 以及重置加载状态.
 */
public class ResponseHandler<T> {
    public static final String SUCCESS_STATUS = "200";//请求成功

    public static final String SUCCESS_STATUS_OTHER = "201";
    private static final String ERROR_STATUS = "500";//请求失败
    private static final String ERROR_STATUS_2 = "503";//请求失败
    public static final String TOKEN_ERROR_STATUS = "401";//token失效
    private boolean isTokenExpired = false;//token是否过期
    private BaseView view;
    private CustomHandler<T> handler;


    public ResponseHandler(CustomHandler<T> handler) {
        this.handler = handler;
    }

    public ResponseHandler(CustomHandler<T> handler, BaseView view) {
        this.handler = handler;
        this.view = view;
    }

    private Handler mhandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                handler.requestAgain();
            }
        }
    };

    public void onCompleted() {
        if (!isTokenExpired)
            release();
    }

    public void onRequestAgainProtocol() {

        mhandler.sendEmptyMessage(0);
    }

    public void onError(Throwable e) {
        resetLoadingStatus();
        e.printStackTrace();
        if (!handler.error(e)) {
            handleException(e);
        }
    }

    public void onNext(T t) {
        resetLoadingStatus();
        if (t instanceof BaseData) {
            isTokenExpired = false;
            JSONObject json = (JSONObject) JSON.toJSON(t);
            String status = json.getString("status");

            Log.v("HttpLogging", "onNext---->" + status);
//            XLog.i("onNext--"+json.toString());
            if (!TextUtils.isEmpty(status)) {
                if (status.equalsIgnoreCase(SUCCESS_STATUS)) {
                    handler.success(t);
                } else if (status.equalsIgnoreCase(SUCCESS_STATUS_OTHER)){
                    handler.success(t);
                }
                    else if (status.equalsIgnoreCase(ERROR_STATUS)) {
                    String msg = json.getString("message");
                    RxBus.getDefault().send(new ErrorEvnet());
                    if (!handler.operationError(t, status, msg)) {
                        handleOperationError(msg);
                    }
                } else if (status.equals(TOKEN_ERROR_STATUS)) {
                    isTokenExpired = true;
                    if (t instanceof SystemSetting) {
//                        XLog.i("如果是欢迎页面接口的token过期不做处理");
                    } else {
                        boolean standard = PreferenceManager.getDefaultSharedPreferences(view.getViewContext()).getBoolean(Constant.STANDARD, false);
                        if (standard) {
                            if (view instanceof LoginActivity) {

                            } else if (view instanceof PresionInfoActivity) {
                                handler.success(t);
                            } else {
                                Utility.startLoginActivity(view.getViewContext());
                            }

                        } else {
//                            Toast.makeText(view.getViewContext(),"FM的token过期,请重新登录",Toast.LENGTH_SHORT).show();
                            //如果有图片在后台上传通知首页
//                            SdkResult sdkResult = new SdkResult();
//                            sdkResult.setStatus(401);
//                            sdkResult.setMessage("token过期");
//                            RxBus.getDefault().send(sdkResult);
                        }
                    }
//                    new TokenExpiredUtils(view.getViewContext(),this).handleTokenExpired();
                } else {
                    String msg = json.getString("message");
                    if (view != null) {
                        if (view instanceof LoginActivity || view instanceof ForgetPwdActivity) {
                            if (!msg.contains("ResponseResult") && !msg.contains("accessToken")) {
                                ToastUtils.showShort(view.getViewContext(), msg);
                            }
                        } else {
                            String tips = "";
                            if (msg.contains("Authentication")) {
                                tips = view.getViewContext().getResources().getString(R.string.tips_authentication);
                            } else {
                                tips = msg;
                            }
                            final ErrorDialog dialog = new ErrorDialog(view.getViewContext(), tips, msg);
                            dialog.show();
                            view.hideLoading();
                        }
                    }

                }
            }
        } else {
            ToastUtils.showShort(view.getViewContext(), "数据异常，请再试一次。");
        }
        if (!isTokenExpired)
            release();
    }

    public void resetLoadingStatus() {
        if (!H5Activity.isDuoxuan) {
            if (view != null) {
                view.hideLoading();
            }
        }
    }


    public void release() {
        view = null;
        handler = null;
    }

    public void handleException(Throwable e) {
        Log.e("HttpLogging3333", "数据异常--->" + e.getMessage());
        if (view != null) {
            if (e instanceof ConnectException) {
                //无法连接服务器，请联系管理员
            } else if (e instanceof HttpException) {
                //记得打开这里
                if (view instanceof LoginActivity) {

                } else {
                    ToastUtils.showShort(view.getViewContext(), view.getViewContext().getString(R.string.network_server_error));
                }
            } else if (e instanceof UnknownHostException) {
            } else if (e instanceof SocketTimeoutException) {
                //无法连接服务器，请联系管理员
                ToastUtils.showShort(view.getViewContext(), view.getViewContext().getString(R.string.network_timeout));
            } else if (e instanceof ConnectException) {
                //Log.e("HttpLogging1111", "数据异常--->" + e.getMessage());

            } else if (e instanceof SSLHandshakeException) {
                DialogUtils.dialogSSL = true;
                if(!(view instanceof LoginActivity)){
                    if (Constant.isSll) {
                        Constant.isSll = false;
                        DialogUtils.insertDialog().dialogCenterComm(view.getViewContext(), view.getViewContext().getString(R.string.kindly_reminder),
                                view.getViewContext().getString(R.string.sslguoqi), false, new OnDialogSureListener() {
                                    @Override
                                    public void onDialogSureListener() {

                                    }
                                });
                    }
                }
                Log.e("HttpLoggingSSL1", "数据异常--->" + e.getMessage());
            } else {
                Log.e("HttpLogging", "数据异常--->" + e.getMessage());
                ToastUtils.showShort(view.getViewContext(), view.getViewContext().getString(R.string.network_other));
            }
        }
    }

    public void handleOperationError(String message) {
        if (getAppication() != null) {
            if (!TextUtils.isEmpty(message))
                ToastUtils.showShort(getAppication(), message);
        }
//        if (view != null)
        //                ToastUtils.showShort(view.getViewContext(), message);

    }


    public interface CustomHandler<T> {
        /**
         * 请求成功同时业务成功的情况下会调用此函数
         */
        void success(T t);

        /**
         * 请求成功但业务失败的情况下会调用此函数.
         *
         * @return 是否需要自行处理业务错误.
         * <p>
         * true - 需要, 父类不会处理错误
         * </P>
         * false - 不需要, 交由父类处理
         */
        boolean operationError(T t, String status, String message);

        /**
         * 请求失败的情况下会调用此函数
         *
         * @return 是否需要自行处理系统错误.
         * <p>
         * true - 需要, 父类不会处理错误
         * </P>
         * false - 不需要, 交由父类处理
         */
        boolean error(Throwable e);

        void requestAgain();
    }


    public Application getAppication() {
        Application application = null;
        Class<?> activityThreadClass;
        try {
            activityThreadClass = Class.forName("android.app.ActivityThread");
            Field appField = activityThreadClass
                    .getDeclaredField("mInitialApplication");
            // Object object = activityThreadClass.newInstance();
            final Method method = activityThreadClass.getMethod(
                    "currentActivityThread", new Class[0]);
            // 得到当前的ActivityThread对象
            Object localObject = method.invoke(null, (Object[]) null);
            appField.setAccessible(true);
            application = (Application) appField.get(localObject);
            // appField.
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return application;
    }

}
